#include "monitor.h"
#include "common.h"

#define BLACK 0
#define BLUE 1
#define GREEN 2
#define CYAN 3
#define RED 4
#define MARGENTA 5
#define BROWN 6
#define LIGHTGREY 7
#define DARKGREY 8
#define LIGHTBLUE 9
#define LIGHTGREEN 10
#define LIGHTCYAN 11
#define LIGHTRED 12
#define LIGHTMAGNETA 13
#define LIGHTBROWN 14
#define WHITE 15

#define SPACE 0x20

u16 *video_memory = (u16*) 0xB8000;
u8 cursor_x;
u8 cursor_y;

void scroll()
{
	u8 attribute_byte = (BLACK << 4) | (WHITE & 0x0F);
	u16 blank = SPACE | (attribute_byte << 8);
	if(cursor_y >= 25) {
		int i;
		for (i = 0*80; i < 24*80; i++) {
			video_memory[i] = video_memory[i+80];
		}
		for (i = 24*80; i < 25*80; i++) {
			video_memory[i] = blank;
		}
		cursor_y = 24;
	}
}

void monitor_clear()
{
	u8 attributeByte = (BLACK << 4) | (WHITE & 0x0F);
	u16 blank = SPACE | (attributeByte << 8);
	int i;
	for (i = 0; i < 80*25; i++) {
		video_memory[i] = blank;
	}
	cursor_x = 0;
	cursor_y = 0;
	move_cursor();
}

void move_cursor()
{
	u16 cursorLocation = cursor_y * 80 + cursor_x;
	// set the cursor high byte
	outb(0x3D4, 14);                  
	outb(0x3D5, cursorLocation >> 8); 

	// set the cursor low byte
	outb(0x3D4, 15);
	outb(0x3D5, cursorLocation);
} 


void monitor_put(char c) 
{
   u8 backColour = BLACK;
   u8 foreColour = WHITE;
   u8  attributeByte = (backColour << 4) | (foreColour & 0x0F);
   u16 attribute = attributeByte << 8;
   u16 *location;
   if (c == 0x08 && cursor_x) {
       cursor_x--;
   } else if (c == 0x09) {
       cursor_x = (cursor_x+8) & ~(8-1);
   } else if (c == '\r') {
       cursor_x = 0;
   } else if (c == '\n') {
       cursor_x = 0;
       cursor_y++;
   } else if(c >= ' ') {
       location = video_memory + (cursor_y*80 + cursor_x);
       *location = c | attribute;
       cursor_x++;
   }

   if (cursor_x >= 80) {
       cursor_x = 0;
       cursor_y ++;
   }
   scroll();
   move_cursor();
}

void monitor_write(char *input) 
{
	int i = 0;
	while (input[i])
		monitor_put(input[i++]);
} 
